package cn.sc.summer.constant.util;

import cn.hutool.core.util.StrUtil;
import lombok.Data;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 类名：匹配类工具，支持通配符和正则表达式
 *
 * @author a-xin
 * @date 2023/8/31 10:38
 */
public class MatchUtil {

    /**
     * 通配符匹配器
     */
    private final static PathMatcher MATCHER = new AntPathMatcher();

    /**
     * 单值匹配单个通配符
     *
     * @param pattern 通配符，例如：/user/login/*
     * @param value   需要匹配的值，例如：/user/login/sign
     * @return ture: 匹配 false: 不匹配
     */
    public static boolean matchPattern(String pattern, String value) {
        if (StrUtil.isBlank(pattern)) {
            throw new RuntimeException("The matching pattern cannot be empty.");
        }
        if (StrUtil.isBlank(value)) {
            throw new RuntimeException("The matching value cannot be empty.");
        }
        return MATCHER.match(pattern, value);
    }

    /**
     * 多值匹配单个通配符
     *
     * @param pattern 通配符，例如：/user/login/*
     * @param values  需要匹配的值，例如：/user/login/sign
     * @return ture: 至少有一个值匹配 false: 所有值都不匹配
     */
    public static boolean anyMatchPattern(String pattern, String... values) {
        if (StrUtil.isBlank(pattern)) {
            throw new RuntimeException("The matching pattern cannot be empty.");
        }
        for (String value : values) {
            if (MATCHER.match(pattern, value)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 多值匹配单个通配符
     *
     * @param pattern 通配符，例如：/user/login/*
     * @param values  需要匹配的值，例如：/user/login/sign
     * @return 匹配结果集
     */
    public static MatchResult anyMatchPatternResult(String pattern, String... values) {
        if (StrUtil.isBlank(pattern)) {
            throw new RuntimeException("The matching pattern cannot be empty.");
        }
        MatchResult matchResult = new MatchResult();
        matchResult.setMatch(true);
        Map<Boolean, Map<String, String>> resultMap = new HashMap<>();
        Map<String, String> matchMapTure = new HashMap<>();
        Map<String, String> matchMapFalse = new HashMap<>();
        for (String value : values) {
            if (MATCHER.match(pattern, value)) {
                matchMapTure.put(pattern, value);
            } else {
                matchMapFalse.put(pattern, value);
            }
        }
        if (matchMapTure.isEmpty()) {
            matchResult.setMatch(false);
        }
        resultMap.put(true, matchMapTure);
        resultMap.put(false, matchMapFalse);
        matchResult.setResultMap(resultMap);
        return matchResult;
    }

    /**
     * 多值匹配单个通配符
     *
     * @param pattern 通配符，例如：/user/login/*
     * @param values  需要匹配的值，例如：/user/login/sign
     * @return ture: 所有值都匹配 false: 不是所有值都匹配
     */
    public static boolean allMatchPattern(String pattern, String... values) {
        if (StrUtil.isBlank(pattern)) {
            throw new RuntimeException("The matching pattern cannot be empty.");
        }
        for (String value : values) {
            if (!MATCHER.match(pattern, value)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 单个值匹配多个通配符
     *
     * @param pattern 通配符，例如：/user/login/*, /user/signOut/*
     * @param value   需要匹配的值，例如：/user/login/sign
     * @return ture: 至少有一个值匹配 false: 所有值都不匹配
     */
    public static boolean anyMatchValue(String value, String... pattern) {
        if (StrUtil.isBlank(value)) {
            throw new RuntimeException("The matching value cannot be empty.");
        }
        for (String patter : pattern) {
            if (MATCHER.match(patter, value)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 单个值匹配多个通配符
     *
     * @param pattern 通配符，例如：/user/login/*, /user/signOut/*
     * @param value   需要匹配的值，例如：/user/login/sign
     * @return ture: 至少有一个值匹配 false: 所有值都不匹配
     */
    public static boolean anyMatchValue(String value, List<String> pattern) {
        if (StrUtil.isBlank(value)) {
            throw new RuntimeException("The matching value cannot be empty.");
        }
        for (String patter : pattern) {
            if (MATCHER.match(patter, value)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 单个值匹配多个通配符
     *
     * @param pattern 通配符，例如：/user/login/*, /user/signOut/*
     * @param value   需要匹配的值，例如：/user/login/sign
     * @return ture: 所有值都匹配 false: 不是所有值都匹配
     */
    public static boolean allMatchValue(String value, String... pattern) {
        if (StrUtil.isBlank(value)) {
            throw new RuntimeException("The matching value cannot be empty.");
        }
        for (String patter : pattern) {
            if (!MATCHER.match(patter, value)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 单值匹配单正则表达式
     *
     * @param regex 正则表达式
     * @param value 需要匹配的值
     * @return 是否匹配
     */
    public static boolean matchRegex(String regex, String value) {
        if (StrUtil.isBlank(regex)) {
            throw new RuntimeException("The matching regex cannot be empty.");
        }
        if (StrUtil.isBlank(value)) {
            throw new RuntimeException("The matching value cannot be empty.");
        }
        return value.matches(regex);
    }

    /**
     * 多值匹配单个正则表达式
     *
     * @param regex  正则表达式
     * @param values 需要匹配的值
     * @return ture: 至少有一个匹配 false: 所有值都不匹配
     */
    public static boolean anyMatchRegex(String regex, String... values) {
        if (StrUtil.isBlank(regex)) {
            throw new RuntimeException("The matching regex cannot be empty.");
        }
        for (String value : values) {
            if (value.matches(regex)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 多值匹配单个正则表达式
     *
     * @param regex  正则表达式
     * @param values 需要匹配的值
     * @return ture: 所有值都匹配 false: 不是所有值都匹配
     */
    public static boolean allMatchRegex(String regex, String... values) {
        if (StrUtil.isBlank(regex)) {
            throw new RuntimeException("The matching regex cannot be empty.");
        }
        for (String value : values) {
            if (!value.matches(regex)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 匹配结果返回值信息处理
     */
    @Data
    static class MatchResult implements Serializable {

        private static final long serialVersionUID = 1L;

        /**
         * 匹配结果
         */
        private boolean isMatch;

        /**
         * 匹配内容，key：成功/失败 value：匹配表达式(通配符或者正则表达式) :  匹配的值
         */
        private Map<Boolean, Map<String, String>> resultMap;

    }

}
